接下來題目都會像以下先列出範例 input、output 跟對應的型別
Input: str = 'Jingle bells Batman'
Output: ['Jingle', 'bells', 'Batman']
/**
* @param {string} str
* @return {array}
*/
const words = function(str) {
// 請把 code 寫在這
};
一般函式寫法
const split = (delimiter, string) => string.split(delimiter)
const words = function(str) {
return split(' ', str);
}
words('Jingle bells Batman');
// => ['Jingle', 'bells', 'Batman']
Currying
const _curry = f => a => b => f(a, b)
const _split = _curry((delimiter, string) => string.split(delimiter))
const words = _split(' ')
words('Jingle bells Batman');
// => ['Jingle', 'bells', 'Batman']
Ramda
平常寫程式時,為了方便我們會用一些函式庫例如 lodash 或 underscore,而 Ramda 是FP 界最有名的函式庫,後面會有篇章介紹,這邊只是想強調 Ramda 所有函式都會自動 Curry 相當方便,例如同樣例子用 Ramda 寫會像以下,非常簡潔
const _ = R;
const words = _.split(' ')
Input: str = ['Jingle bells Batman', 'Robin laid an egg']
Output: [['Jingle', 'bells', 'Batman'], ['Robin', 'laid', 'an', 'egg']]
/**
* @param {array} arr
* @return {array}
*/
const sentences = function(arr) {
};
一般函式寫法
const map = (f, arr) => arr.map(f)
const sentences = arr => map(words, arr)
// words 是 practice 1 的函式
sentences(['Jingle bells Batman', 'Robin laid an egg']);
Curry
const _map = f => arr => arr.map(f)
const sentences = _map(words)
// words 是 practice 1 的函式
/* 改成 Ramda 一行結束 ---- */
const sentences = _.map(words)
sentences(['Jingle bells Batman', 'Robin laid an egg']);
Input: xs = ['quick', 'camels', 'quarry', 'over', 'quails']
Output: ['quick', 'quarry', 'quails']
/**
* @param {array} arr
* @return {arr}
*/
const filterQs = function(arr) {
};
一般函式寫法
const filter = (f, arr) => arr.filter(f)
const filterQs = arr => filter(x => x.match(/q/ig), arr)
filterQs(['quick', 'camels', 'quarry', 'over', 'quails']);
// => ["quick", "quarry", "quails"]
Curry
const _filter = f => arr => arr.filter(f)
const filterQs = _filter(x => x.match(/q/ig))
/* 改成 Ramda 一行結束 ---- */
const filterQs = _filter(x => _.test(/q/ig, x))
filterQs(['quick', 'camels', 'quarry', 'over', 'quails']);
// => ["quick", "quarry", "quails"]
Input: xs = [323,523,554,123,5234]
Output: 5234
/**
* @param {array} arr
* @return {number}
*/
const _keepHighest = (x,y) => x >= y ? x : y // <- leave be
const max = function(xs) {
};
一般函式寫法
const max = function(xs) {
return xs.reduce(function(acc, x){
return _keepHighest(acc, x);
}, 0);
}
max([323,523,554,123,5234])
// => 5234
Currying
// 直接用 Ramda
const max = _.reduce(_keepHighest, 0);
max([323,523,554,123,5234])
// => 5234
原始碼 codepen 在這裡
運用 Currying 的 pattern 其實也可以變出其他花樣
add(x)(y) 等同 add(x, y)
const add = (x, y) => x + y;
const curry = f => x => y => f(x, y)
const result = curry(add)(3)(4)
console.log(result) // 7
add([x, y]) 等同 add(x, y)
const add = (x, y) => x + y;
const toPair = f => ([x,y]) => f(x, y)
const result = toPair(add)([1, 2])
console.log(result) // 3
add(y, x) = add(x, y)
const add = (x, y) => x + y;
const flip = f => (y, x) => f(x, y)
const result = flip(add)(1, 3)
console.log(result) // 4
['a', 'b', 'c'].slice(0, 2) 成 slice(1)(3)(['a', 'b', 'c'])
const slice = start => end => array => array.slice(start, end)
如有錯誤或需要改進的地方,拜託跟我說。
我會以最快速度修改,感謝您
歡迎追蹤我的部落格,除了技術文也會分享一些在矽谷工作的甘苦。